package com.easyCode.sqlBuilder.sqlUtil;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.easyCode.sqlBuilder.SqlInfo;
import com.easyCode.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;

import java.util.Arrays;
import java.util.List;

import static com.alibaba.druid.sql.SQLUtils.toSQLString;

/**
 * sql语句构建工具类
 * @author 大忽悠
 * @create 2022/11/29 19:54
 */
@Slf4j
public class SqlBuildUtil {

    /**
     * @param sqlParam 参数
     * @return 返回包装后的参数
     */
    public static String wrapSqlParam(String sqlParam){
        return " `"+sqlParam+"` ";
    }

    /**
     * @param  sqlVal  值
     * @return 返回包装后的值
     */
    public static String wrapSqlVal(String sqlVal){
        return " '" +sqlVal+"' ";
    }

    /**
     * @param  parts 构建sql语句中每一部分
     * @return 返回构建得到的sql语句
     */
    public static String buildSql(String ... parts){
        StringBuilder sql=new StringBuilder();
        sql.append(" ");
        for (String part : parts) {
            //字符串为空,就跳过组装
            if(part==null || part.isEmpty()){
                continue;
            }
            sql.append(part).append(" ");
        }
        return sql.toString();
    }

    /**
     * 分号结尾
     */
    public static String buildSqlWithSemicolon(String ... parts){
        StringBuilder sql=new StringBuilder();
        sql.append(" ");
        for (String part : parts) {
            //字符串为空,就跳过组装
            if(part==null || part.isEmpty()){
                continue;
            }
            sql.append(part).append(" ");
        }
        return sql.append(";").toString();
    }

    public static String buildFiledType(String filedType, String filedLen) {
         return filedLen!=null ? filedType+"("+filedLen+")": filedType;
    }

    public static String assembleIfNeed(Boolean assembleIf, String targetStr) {
          if(assembleIf){
              return targetStr;
          }
          return "";
    }

    public static String assembleIfNeed(String assembleIf, String targetStr) {
        if(assembleIf!=null&&!assembleIf.isEmpty()){
            return targetStr;
        }
        return "";
    }

    public static String assemblerWithDelimiter(List<? extends SqlInfo> list) {
        if(ObjectUtils.isEmpty(list)){
            return "";
        }
        StringBuilder sql = new StringBuilder();
        sql.append(list.get(0).buildSql());
        list.stream().skip(1).filter(sqlInfo -> !sqlInfo.buildSql().isEmpty()).forEach(sqlInfo -> sql.append(",").append(sqlInfo.buildSql()));
        return sql.toString();
    }

    public static String assemblerWithDelimiter(String... sqlArray) {
        if(ObjectUtils.isEmpty(sqlArray)){
            return "";
        }
        StringBuilder sql = new StringBuilder();
        sql.append(sqlArray[0]);
        Arrays.stream(sqlArray).skip(1).filter(s->!s.isEmpty()).forEach(sqlInfo -> sql.append(",").append(sqlInfo));
        return sql.toString();
    }

    public static String assembler(String... sqlArray) {
        if(ObjectUtils.isEmpty(sqlArray)){
            return "";
        }
        StringBuilder sql = new StringBuilder();
        sql.append(sqlArray[0]);
        Arrays.stream(sqlArray).skip(1).forEach(sql::append);
        return sql.toString();
    }

    public static String sqlFormat(String sql) {
        List<SQLStatement> statementList = sqlVerify(sql);
        return toSQLString(statementList, DbType.valueOf("mysql"));
    }

    public static List<SQLStatement> sqlVerify(String sql) {
        List<SQLStatement> statementList = null;
        SQLStatementParser parser = null;
        try {
            parser = SQLParserUtils.createSQLStatementParser(sql, "mysql");
            statementList = parser.parseStatementList();
        } catch (ParserException e) {
            log.error("SQL格式化过程中出现语法解析错误: ",e);
        }
        return statementList;
    }

    public static String assembleIfNeed(Object defaultVal, String s) {
        if(defaultVal==null){
            return null;
        }
        return assembleIfNeed(String.valueOf(defaultVal),s);
    }
}
